package cn.qyd.bloomfilter;

import com.google.common.base.Charsets;
import com.google.common.hash.BloomFilter;
import com.google.common.hash.Funnels;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.UUID;

/**
 * @author 邱运铎
 * 误判率 fpp 的值越小，匹配的精度越高。当减少误判率 fpp 的值，需要的存储空间也越大，所以在实际使用过程中需要在误判率和存储空间之间做个权衡
 * Guava默认设置的误判率是3%，
 * @date 2024-03-10 23:49
 */
public class BloomFilterDemo02 {
    public static void main(String[] args) {
        //这里这是设置误判率为1%，最终结果可以看出确实是接近这个数字的
        //BloomFilter<String> bloomFilter = BloomFilter.create(Funnels.stringFunnel(Charsets.UTF_8),5000000,0.01);
        //默认误判率是3%
        BloomFilter<String> bloomFilter = BloomFilter.create(Funnels.stringFunnel(Charsets.UTF_8),5000000);

        ArrayList<String> list = new ArrayList<>(5000000);
        for(int i = 0; i < 5000000; i++) {
            String uuid = UUID.randomUUID().toString();
            bloomFilter.put(uuid);
            list.add(uuid);
        }

        int mightContainNumber1 = 0;
        NumberFormat percentFormat = NumberFormat.getPercentInstance();
        percentFormat.setMaximumFractionDigits(2);

        for(int i = 0; i < 500; i++) {
            String key = list.get(i);
            if(bloomFilter.mightContain(key)) {
                mightContainNumber1++;
            }
        }

        System.out.println("【key真实存在的情况】布隆过滤器认为存在的key值数： " + mightContainNumber1);
        System.out.println("=================================================================");

        int mightContainNumber2 = 0;
        for (int i = 0; i < 5000000; i++) {
            String key = UUID.randomUUID().toString();
            if (bloomFilter.mightContain(key)) {
                mightContainNumber2++;
            }
        }

        System.out.println("【key不存在的情况】布隆过滤器认为存在的key值数量： " + mightContainNumber2);
        System.out.println("【key不存在的情况】布隆过滤器的误判率： " + percentFormat.format((float)mightContainNumber2/5000000));
    }
}
